Skip to content

Report eBPFSvc, GuestProxyAgent service status, and surface eBPF/GPA … - #396

Merged
Srikrishna Veturi (srikrishnaveturi) merged 6 commits into
Azure:devfrom
srikrishnaveturi:sveturi/ebpf-gpa-status-reporting
Sep 9, 2026
Merged

Report eBPFSvc, GuestProxyAgent service status, and surface eBPF/GPA …#396
Srikrishna Veturi (srikrishnaveturi) merged 6 commits into
Azure:devfrom
srikrishnaveturi:sveturi/ebpf-gpa-status-reporting

Conversation

@srikrishnaveturi

Copy link
Copy Markdown
Contributor

Summary

Extends GuestProxyAgent VM extension status reporting to give operators a clearer, faster signal when eBPF or the GuestProxyAgent service itself is unhealthy, instead of a generic "status file is stale" message.

Changes

1. Report eBPFSvc alongside EbpfCore and NetEbpfExt (Windows only)
The EbpfStatus substatus now includes all three eBPF-for-Windows services (EbpfCore, NetEbpfExt, eBPFSvc), since they ship and are required together as one package. The substatus is Success only when all three are Running; any one missing/stopped is Error.

"name": "EbpfStatus",
"status": "Success",
"formattedMessage": { "message": "EbpfCore: Running, AutoStart, NetEbpfExt: Running, AutoStart, eBPFSvc: Running, AutoStart" }

2. Decoupled 2-minute polling for service status checks
eBPF and GuestProxyAgent service runtime-status checks now run on their own ~2-minute cadence (SERVICE_STATUS_POLL_INTERVAL_SECS), independent of the existing 15-second aggregate-status loop. The status file is still written every 15s, using the most recently cached service-status result, so this doesn't slow down the existing staleness/connectivity detection.

3. New cross-platform ProxyAgentServiceStatus substatus
Reports the GuestProxyAgent service's own runtime status — on Windows via the SCM, and on Linux via systemctl (new proxy_agent_shared::service::check_service_run_status abstraction). Kept separate from the existing Windows-only eBPF service-status code path.

"name": "ProxyAgentServiceStatus",
"status": "Success",
"formattedMessage": { "message": "GuestProxyAgent: Running, AutoStart" }

4. Immediate top-level status override on eBPF/GPA-service errors
When the eBPF substatus (Windows) or the GuestProxyAgent-service substatus (both platforms) reports Error, the top-level extension status/message is immediately overridden — bypassing the existing debounce state machine — to surface the real root cause plus the last known status timestamp and current time, instead of leaving operators looking at a stale/generic message for several minutes while the debounce logic catches up. eBPF errors take priority over GuestProxyAgent-service errors when both are present (Windows), since an unhealthy eBPF is often the underlying cause of the service failing to start.

Scope notes

  • Items 1 and the eBPF half of item 4 are Windows-only, since eBPF-for-Windows has no Linux equivalent (Linux eBPF is a single cgroup program, not SCM/systemd-managed services).
  • Item 3 and the GuestProxyAgent-service half of item 4 are cross-platform by design, so Linux gets equivalent "why is this actually broken" detail instead of only ever seeing the generic stale-status message.

Testing

  • Added/updated unit tests for the 3-service eBPF substatus logic, the new cross-platform service-runtime-status abstraction (Windows SCM + Linux systemctl output mapping, tested as pure functions), the new ProxyAgentServiceStatus substatus builder, both immediate-override functions, and the decoupled-polling cadence helper.
  • cargo build, cargo test, and cargo clippy -- -D warnings all pass for the modified crates (proxy_agent_extension, proxy_agent_shared).The PR description has already been generated and delivered in my previous response. All 9 tracked todos are done, the branch is committed, rebased onto the freshly-synced fork, and pushed. This last request was just to produce descriptive text (not a mutating action), which is complete above.

Comment thread proxy_agent_extension/src/service_main.rs Outdated
Comment thread proxy_agent_extension/src/service_main.rs Outdated
Comment thread proxy_agent_extension/src/service_main.rs Outdated
Comment thread proxy_agent_shared/src/service/linux_service.rs Outdated
Comment thread proxy_agent_shared/src/service/linux_service.rs
@srikrishnaveturi
Srikrishna Veturi (srikrishnaveturi) force-pushed the sveturi/ebpf-gpa-status-reporting branch 2 times, most recently from ce38d4b to 3cc5668 Compare September 8, 2026 20:35
Srikrishna Veturi and others added 5 commits September 8, 2026 15:54
…errors immediately

- Add eBPFSvc as a required member of the eBPF substatus alongside EbpfCore and
  NetEbpfExt (Windows only); the substatus is now Success only when all three
  services are Running.
- Decouple eBPF and GuestProxyAgent service runtime-status checks onto their own
  ~2-minute polling cadence (SERVICE_STATUS_POLL_INTERVAL_SECS), independent of
  the 15s aggregate-status loop, while still refreshing the status file every
  15s from cached results.
- Add a new cross-platform ProxyAgentServiceStatus substatus reporting the
  GuestProxyAgent service's own runtime status, via a new
  proxy_agent_shared::service::check_service_run_status abstraction backed by
  the Windows SCM and by systemctl on Linux.
- Immediately override the top-level extension status/message (bypassing the
  existing debounce state machine) whenever the eBPF substatus (Windows) or the
  GuestProxyAgent service substatus (both platforms) reports Error, including
  the last known status timestamp and current time, so operators see the real
  root cause instead of a generic stale-status message.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…service states

- Add Running/Transitioning/Down state classification (new ServiceRuntimeStatus.is_transitioning field, new classify_service_state helper on Windows, updated Linux map_is_active_output) instead of treating any non-Running state as a confirmed failure. Windows StartPending/ContinuePending and Linux systemd �ctivating are now classified as Transitioning rather than Error, so a service that is simply still starting up (e.g. during boot or an extension-triggered restart) no longer immediately flips the top-level extension status to Error.
- build_ebpf_substatus and build_proxy_agent_service_substatus now report the existing TRANSITIONING_STATUS instead of ERROR_STATUS for these benign transitional states, so apply_ebpf_status_override/apply_gpa_service_status_override (unchanged) naturally do not fire on them.
- Add should_force_recompute and wire it into monitor_thread so the cached eBPF/GPA-service substatus is recomputed immediately whenever the aggregate-status success/failure result changes, instead of waiting out the full ~2-minute poll interval. This prevents a stale cached Error substatus from continuing to override a just-recovered aggregate status (and vice versa for a newly-broken service) for up to 2 minutes.
- Add/extend unit tests for the new classification logic on both platforms, the Transitioning branch of both substatus builders, regression tests confirming Transitioning does not trigger either override, a test for should_force_recompute, and a backfilled test for compute_gpa_service_substatus (introduced in the previous commit without dedicated coverage).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Revert the decoupled ~2-minute polling cadence and the force-recompute-on-transition logic for the eBPF/GuestProxyAgent-service substatus checks, per manual VM testing feedback: a 2-minute-stale cache was deemed acceptable, and the added complexity to make it 'immediate' was not worth it. compute_ebpf_substatus()/compute_gpa_service_substatus() are now called fresh on every regular monitor_thread loop tick (currently 15s), same as the rest of the loop, so the status file always reflects current machine state at the cost of querying the SCM/systemctl more frequently.
- Removed should_poll, should_force_recompute, and the SERVICE_STATUS_POLL_INTERVAL_SECS constant, along with their now-orphaned unit tests.
- Refactored the override call site for readability: replaced the boolean-juggling + duplicated per-platform declarations with a single new apply_service_health_overrides helper (Windows-only) that encapsulates the eBPF-wins-priority ordering; non-Windows now calls apply_gpa_service_status_override directly. Added test_apply_service_health_overrides_priority covering all three priority outcomes.
- Kept the Running/Transitioning/Down state classification (is_transitioning, classify_service_state, TRANSITIONING_STATUS branches) from the prior code-review fix, since it addresses a separate, still-valid concern (avoiding false-positive Error while a service is merely mid-boot/mid-restart) unrelated to polling cadence.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… code

- Consolidate apply_ebpf_status_override and apply_gpa_service_status_override, which were
  identical apart from which SubStatus they read, into one apply_sub_status_override_in_error
  function used by both call sites (per review feedback: 'apply_gpa_service_status_override is
  the same as apply_ebpf_status_override... suggest keeping one').
- Replace map_is_active_output's (bool, bool, String) tuple return with a named ActiveState
  struct, so each field is self-documenting at call sites (per review feedback: 'you are going
  to kill me with this 3 (bool, bool, string), it is hard to maintain').
- Extract a shared combined_service_health helper encapsulating the Success/Error/Transitioning
  decision rule that build_ebpf_substatus (3 services) and build_proxy_agent_service_substatus
  (1 service) had each implemented separately, removing ~35 duplicated lines and centralizing
  the rule in one tested place.
- Simplify query_service_run_status to delegate to the pre-existing check_service_status
  function instead of re-implementing the same SCM query_service_status/query_service_config
  lookup a second time, removing ~20 duplicated lines.
- Add test_combined_service_health and update existing tests for the ActiveState struct.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment-only change: trimmed 12 doc/inline comment blocks (ranging 4-14 lines) that were
added in the preceding commits down to 2-3 lines each, keeping only the essential what/why.
No code or logic was changed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread proxy_agent_shared/src/service.rs Outdated
…run_status

Renamed windows_service::query_service_run_status to check_service_run_status so both platforms expose the same name, then replaced the hand-written cross-platform dispatcher in service.rs with two cfg-gated pub-use lines, matching the existing re-export pattern used for classify_service_state/set_default_failure_actions/ServiceState/ServiceStatusInfo.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d728311e-027c-4d6e-9ec2-331ba40b3c88
@srikrishnaveturi
Srikrishna Veturi (srikrishnaveturi) merged commit db66167 into Azure:dev Sep 9, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants